<?php
//=======================================
//###################################
// Kayako Web Solutions
//
// Source Copyright 2001-2004 Kayako Web Solutions
// Unauthorized reproduction is not allowed
// License Number: $%LICENSE%$
// $Author: vshoor $ ($Date: 2006/09/26 21:30:56 $)
// $RCSfile: functions_search.php,v $ : $Revision: 1.12 $ 
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//###################################
//=======================================


if (!defined("INSWIFT")) {
	trigger_error("Unable to process $PHP_SELF", E_USER_ERROR);
}

/**
* Builds up the post index for given ticket post.
*/
function buildTicketPostIndex($ticketpostid, $indexcontents = "", $indexsubject = "")
{
	global $dbCore, $_SWIFT;

/*	// If we are using full text searches then dont index this post
	if ($_SWIFT["settings"]["tickets_searchtype"] == SEARCH_FULLTEXT)
	{
		return false;
	}
*/
	$wordlist = $insubjectwords = $faulttolerance = $wordidlist = $contentwordscache = $postindexsql = $subjectwordlist = array();

	if (!empty($indexsubject))
	{
		$_ticketpostdata["subject"] = $indexsubject;
	}

	// Is the supplied text empty? If yes, we try to fetch it from the inserted post
	if (empty($indexcontents))
	{
		$_ticketpostdata = $dbCore->queryFetch("SELECT `ticketpostid`, `subject`, `contents` FROM `". TABLE_PREFIX ."ticketposts` WHERE `ticketpostid` = '". intval($ticketpostid) ."';");
		if (empty($_ticketpostdata["ticketpostid"]))
		{
			// No such post in there?
			return false;
		}

		$indexcontents = $_ticketpostdata["subject"]." ".$_ticketpostdata["contents"];
		unset($_ticketpostdata);
	} else if (trim($indexsubject) != "") {
		$indexcontents .= " ".$indexsubject;
	}


	// Is the subject set?
	if (isset($_ticketpostdata["subject"]))
	{
		$subjectwordsdata = returnSanitizedText($_ticketpostdata["subject"]);
		$subjectwordlist = explode(" ", $subjectwordsdata);

		foreach ($subjectwordlist as $key=>$val)
		{
			$insubjectwords[] = $val;
			$tolerancescore[$val]++;
		}
	}

	// Now process all contents, this will include subject
	$contentwords = returnSanitizedText($indexcontents);
	$contentwordlist = array_merge(explode(" ", $contentwords), $subjectwordlist);

	foreach ($contentwordlist as $key=>$val)
	{
		$faulttolerance[$val]++;
	}

	// Fetch the word ids for all the words
	$dbCore->query("SELECT `ticketwordid`, `contents` FROM `". TABLE_PREFIX ."ticketwords` WHERE `contents` IN ('". str_replace(" ", "','", " ".$contentwords." ") ."');");
	while ($dbCore->nextRecord())
	{
		$wordidlist[$dbCore->Record["contents"]] = $dbCore->Record["ticketwordid"];
	}

	// We now iterate through all the words
	$wordcount = 0;
	foreach ($contentwordlist as $key=>$word)
	{
		// Should we index this word?
		if (!shouldIndexWord($word))
		{
			continue;
		}

		// Is the fault tolerance score more than the one set in settings?
		if ($faulttolerance[$word] > $_SWIFT["settings"]["tickets_faulttolerance"])
		{
			continue;
		}

		// Does this word exist in our index? If yes.. we simply insert the post index entry
		if (!empty($wordidlist[$word]))
		{
			if (in_array($word, $subjectwordlist))
			{
				$insubject = "1";
			} else {
				$insubject = "0";
			}

			$postindexsql[] = "('". intval($wordidlist[$word]) ."', '". intval($ticketpostid) ."', '". $insubject ."')";
		} else {
			$insertwordsql .= trim($word)." ";
			$wordcount++;
		}
	}

//	echo $insertwordsql;
//	exit;

	// Are we supposed to insert any post <> word links?
	if (count($postindexsql))
	{
		$dbCore->query("REPLACE INTO `". TABLE_PREFIX ."ticketpostindex` (`ticketwordid`, `ticketpostid`, `insubject`) VALUES ".implode(",",$postindexsql).";");
	}

	// Are we supposed to insert any new words?
	if (!empty($insertwordsql))
	{
		$insertwordsql = trim($insertwordsql);

		// Houston we have a new word!
		$dbCore->query("INSERT IGNORE INTO `". TABLE_PREFIX ."ticketwords` (`contents`) VALUES ('". str_replace(" ", "') , ('", $insertwordsql)."');");

		// Insert the post <> word link
		$dbCore->query("INSERT IGNORE INTO `". TABLE_PREFIX ."ticketpostindex` (`ticketwordid`, `ticketpostid`, `insubject`) SELECT DISTINCT ticketwordid, '". intval($ticketpostid) ."', '0' FROM `". TABLE_PREFIX ."ticketwords` WHERE `contents` IN ('". str_replace(" ", "', '", $insertwordsql) ."');");
	}

	if (empty($wordcount))
	{
		return 0;
	}

	return $wordcount;
}

/**
* returns Boolean value depending upon the various settings configured
*/
function shouldIndexWord($word)
{
	global $_SWIFT, $stopwords;

	require_once ("./modules/tickets/global_searchstopwords.php");
	$_matches = array();

	$wordlength = strlen($word);
	$isnumber = preg_match("/^([0-9]+)$/", $word);
	if ($wordlength < $_SWIFT["settings"]["tickets_minwordlength"] || $wordlength > $_SWIFT["settings"]["tickets_maxwordlength"])
	{
		return false;
	} else if (in_array(strtolower($word), $stopwords)) {
		return false;
	} else if ($isnumber && $_SWIFT["settings"]["tickets_indexnumbers"] != 1) {
		// Its a number and we arent supposed to index it.. return false
		return false;
	} else if ($isnumber && $wordlength < $_SWIFT["settings"]["tickets_minnumberlength"]) {
		// Its a number and its length is less than the minimum number length.. false false!
		return false;
	} else if ($_SWIFT["settings"]["t_signores"] == 1 && !ereg('^[[:alnum:]]+$', $word) && !preg_match('/&#(x[a-f0-9]+|[0-9]+);/i', trim($word), $_matches)) {
		// Word has symbol in it, return false..
		return false;
	}

	return true;
}


/**
* Returns a sanitized text for searches.. strips text of all symbols and returns a space delimited text
*/
function returnSanitizedText($contents)
{
	// Strip HTML Tags
	$contents = strip_tags($contents);

	// Strips white spaces, words containing asterisks, new lines and all symbols
	$stopdata = array("#\s+#s", "#(\r\n|\r|\n)#s", "/[^a-zA-Z0-9\-\_\s\x80-\xff\&\#;]/");

	$replacewith = array(" ", " ", "");
	$contents = preg_replace($stopdata, $replacewith, $contents);

	$contents = preg_replace('/&#(x[a-f0-9]+|[0-9]+);/i', ' &#$1; ', $contents);

	return trim($contents);
}

/**
* Fetches the ticketwordids as array for a given ticket post
*/
function fetchWordsArrayForTicketPost($ticketpostidlist)
{
	global $dbCore;

	$wordlist = $ticketwordidlist = array();

	if (!_is_array($ticketpostidlist))
	{
		return false;
	}

	// Build the words from given post
	$dbCore->query("SELECT `subject`, `contents` FROM `". TABLE_PREFIX ."ticketposts` WHERE `ticketpostid` IN (". buildIN($ticketpostidlist) .");");
	while ($dbCore->nextRecord())
	{
		$wordlist = array_merge($wordlist, explode(" ", returnSanitizedText($dbCore->Record["subject"]." ".$dbCore->Record["contents"])));
	}

	// Now Fetch the word ids for given words
	$dbCore->query("SELECT `ticketwordid` FROM `". TABLE_PREFIX ."ticketwords` WHERE `contents` IN ('". buildIN($wordlist) ."');");
	while ($dbCore->nextRecord())
	{
		$ticketwordidlist[] = $dbCore->Record["ticketwordid"];
	}

	return $ticketwordidlist;
}

/**
* Fetches the ticketwordids as a comma delimted string for a given ticket post
*/
function fetchWordsListForTicketPost($ticketpostidlist, $text)
{
	global $dbCore;

	$wordlist = " ";

	if (!_is_array($ticketpostidlist))
	{
		return false;
	}

	// Build the words from given post
	$wordlist = returnSanitizedText($text);
	$wordarray = explode(" ", $wordlist);

	// Now Fetch the word ids for given words
	$dbCore->query("SELECT `ticketwordid` FROM `". TABLE_PREFIX ."ticketwords` WHERE `contents` IN (". buildIN($wordarray) .");");
	while ($dbCore->nextRecord())
	{
		$ticketwordidlist .= ",".intval($dbCore->Record["ticketwordid"]);
	}

	return $ticketwordidlist;
}

/**
* Empties entire index
*/
function emptyEntireSearchIndex()
{
	global $dbCore;

	$dbCore->query("DELETE FROM `". TABLE_PREFIX ."ticketpostindex`;");
	$dbCore->query("DELETE FROM `". TABLE_PREFIX ."ticketwords`;");

	return true;
}

/**
* Empty the index for given ticket post
*/
function emptyTicketPostIndex($ticketpostidlist, $text)
{
	global $dbCore;

	$ticketwordidlist = array();

	// Fetch all word ids for this post
	$ticketwordidlist = fetchWordsListForTicketPost($ticketpostidlist, $text);

	if (empty($ticketwordidlist))
	{
		return false;
	}

	// Empty the post index
	$dbCore->query("DELETE FROM `". TABLE_PREFIX ."ticketpostindex` WHERE `ticketwordid` IN (0". $ticketwordidlist .") AND `ticketpostid` IN (". buildIN($ticketpostidlist) .");");

	return true;
}

/**
* Empty the search index for given ticket
*/
function emptyTicketIndex($ticketid)
{
	global $dbCore;

	$ticketpostidlist = $ticketwordidlist = array();

	// Fetch all post ids for given ticket
	$dbCore->query("SELECT `ticketpostid` FROM `". TABLE_PREFIX ."ticketposts` WHERE `ticketid` = '". intval($ticketid) ."';");
	while ($dbCore->nextRecord())
	{
		$ticketpostidlist[] = $dbCore->Record["ticketpostid"];
	}

	// Fetch all word ids
	$ticketwordidlist = fetchWordsForTicketPost($ticketpostidlist);

	if (empty($ticketwordidlist))
	{
		return false;
	}

	// Empty the post index
	$dbCore->query("DELETE FROM `". TABLE_PREFIX ."ticketpostindex` WHERE `ticketwordid` IN (0". $ticketwordidlist .") AND `ticketpostid` IN (". buildIN($ticketpostidlist) .");");

	// All done, the post index for this ticket is gone now!

	return true;
}
?>